import React, { memo, forwardRef } from 'react';
import { DatePicker as AntDatePicker } from 'antd';
import type { DatePickerProps as AntDatePickerProps } from 'antd';
import dayjs from 'dayjs';
import type { Dayjs } from 'dayjs';
import classNames from 'classnames';
import styles from './DatePicker.module.css';

/**
 * 日期选择器组件属性接口
 * @description 扩展 Ant Design DatePicker 组件的属性
 */
export interface IDatePickerProps extends Omit<AntDatePickerProps, 'value' | 'defaultValue' | 'onChange' | 'minDate' | 'maxDate'> {
  /** 当前值 */
  value?: string | Dayjs | null;
  /** 默认值 */
  defaultValue?: string | Dayjs | null;
  /** 值变化回调 */
  onChange?: (date: string | null, dateString: string) => void;
  /** 日期格式 */
  format?: string;
  /** 是否显示今天按钮 */
  showToday?: boolean;
  /** 是否显示清除按钮 */
  allowClear?: boolean;
  /** 占位符文本 */
  placeholder?: string;
  /** 是否禁用 */
  disabled?: boolean;
  /** 是否只读 */
  readonly?: boolean;
  /** 组件尺寸 */
  size?: 'small' | 'middle' | 'large';
  /** 最小日期 */
  minDate?: string | Dayjs;
  /** 最大日期 */
  maxDate?: string | Dayjs;
  /** 禁用日期函数 */
  disabledDate?: (current: Dayjs) => boolean;
  /** 自定义类名 */
  className?: string;
}

/**
 * 日期选择器组件
 * @description 基于 Ant Design DatePicker 的自定义日期选择器，提供统一的日期格式处理
 */
const DatePicker = memo(forwardRef<any, IDatePickerProps>(({
  value,
  defaultValue,
  onChange,
  format = 'YYYY-MM-DD',
  showToday = true,
  allowClear = true,
  placeholder = '请选择日期',
  disabled = false,
  readonly = false,
  size = 'middle',
  minDate,
  maxDate,
  disabledDate,
  className,
  ...props
}, ref) => {
  // 转换字符串日期为 Dayjs 对象
  const convertToDateValue = (dateValue?: string | Dayjs | null): Dayjs | null => {
    if (!dateValue) {
      return null;
    }

    if (typeof dateValue === 'string') {
      const parsed = dayjs(dateValue);
      return parsed.isValid() ? parsed : null;
    }

    return dayjs.isDayjs(dateValue) ? dateValue : null;
  };

  // 处理值变化
  const handleChange = (date: Dayjs | null, dateString: string | string[]) => {
    if (onChange) {
      const stringValue = date ? date.format(format) : null;
      const finalDateString = Array.isArray(dateString) ? dateString[0] : dateString;
      onChange(stringValue, finalDateString);
    }
  };

  // 处理禁用日期
  const handleDisabledDate = (current: Dayjs): boolean => {
    // 自定义禁用日期函数优先
    if (disabledDate) {
      return disabledDate(current);
    }

    let disabled = false;

    // 检查最小日期限制
    if (minDate) {
      const min = convertToDateValue(minDate);
      if (min && current.isBefore(min, 'day')) {
        disabled = true;
      }
    }

    // 检查最大日期限制
    if (maxDate) {
      const max = convertToDateValue(maxDate);
      if (max && current.isAfter(max, 'day')) {
        disabled = true;
      }
    }

    return disabled;
  };

  // 获取当前值
  const getCurrentValue = (): Dayjs | null => {
    return convertToDateValue(value);
  };

  // 获取默认值
  const getDefaultValue = (): Dayjs | null => {
    return convertToDateValue(defaultValue);
  };

  // 组合类名
  const datePickerClassName = classNames(
    styles.datePicker,
    {
      [styles.small]: size === 'small',
      [styles.large]: size === 'large',
      [styles.disabled]: disabled,
      [styles.readonly]: readonly,
    },
    className
  );

  return (
    <AntDatePicker
      ref={ref}
      value={getCurrentValue()}
      defaultValue={getDefaultValue()}
      onChange={handleChange}
      format={format}
      showToday={showToday}
      allowClear={allowClear}
      placeholder={placeholder}
      disabled={disabled || readonly}
      size={size}
      disabledDate={handleDisabledDate}
      className={datePickerClassName}
      {...props}
    />
  );
}));

DatePicker.displayName = 'DatePicker';

export default DatePicker;